perm filename RECOG0.SAI[SYS,HE]1 blob sn#016491 filedate 1972-12-06 generic text, type T, neo UTF8
COMMENT ⊗   VALID 00013 PAGES 
RECORD PAGE   DESCRIPTION
 00001 00001
 00002 00002	ENTRY DUMMY
 00003 00003	α	DISKSEG
 00008 00004	α	DISKOUT
 00011 00005	α	DISKPRE
 00014 00006	α	COMPLETE
 00016 00007	α	PARTPP
 00018 00008	α	PARTFT
 00020 00009	α	SUBSEG1
 00023 00010	α	PARTBEL
 00025 00011	α	PARTBA
 00027 00012	α	PARTNVP
 00028 00013	α	PARTLAC
 00030 ENDMK
⊗;
ENTRY DUMMY;

BEGIN "RECOG0"

REQUIRE	100	PNAMES;
REQUIRE	"PREAMB.SAI[SYS,HE]"	SOURCE_FILE;
REQUIRE	"SYMBOL.AUX[H,RPO]"	SOURCE_FILE;
REQUIRE	"RECCOM.AUX[SYS,HE]"	SOURCE_FILE;


α LOCALS;
INTEGER FLAG,ERRFLAG;

α EXTERNAL PROCEDURES;

ERP		 ANGLE(SAFE REAL ARRAY ITEMVAR P1,P2,P3; INTEGER D);
EBP		 VERT(ITEMVAR E);
ESP		PRINTNAME(ITEMVAR X);
α	DISKSEG
read a body .SEG file and copy into the global segment;

INTERNAL PROCEDURE DISKSEG;
BEGIN "DISKSEG"
INTEGER I,J,BREAK,EOF,NUMB,NUML,NUMP,NUMF,NUMO,NUMA;
SAFE REAL ARRAY FOURBY4[1:4,1:4],SIZE4[1:4],XFRM[1:10,1:3];
SAFE REAL ARRAY ITEMVAR GB,GC,GP;
SET ITEMVAR GSIV;
SET VSET;
ITEMVAR GL,GF;
STRING FILENAME,PNAME,STR;

DEFINE	ROW=<1>, PARE=<2>, ID=<3>,
	TOKEN=<PNAME←SCAN(STR,PARE,BREAK); PNAME←SCAN(STR,ID,BREAK);>,
	NEXTLINE=<STR←INPUT(1,ROW);>,
	REPEAT=<>,
	PROPERTY=<>,
	TIMES=<>,
	GETPNAME=<DO ⊂ NEXTLINE TOKEN ⊃ UNTIL PNAME="G";>,
OCCLUDERS=
	<NUMO←INTIN(1);
	 FOR I←1 STEP 1 UNTIL NUMO DO
	⊂ GETPNAME GB←CVSI(PNAME,J); TOKEN GC←CVSI(PNAME,J);
	 $ MAKE OCCLUDER⊗GB≡GC; ⊃;>,
ABOVES=
	<NUMA←INTIN(1);
	 FOR I←1 STEP 1 UNTIL NUMA DO
	⊂ GETPNAME GB←CVSI(PNAME,J); TOKEN GC←CVSI(PNAME,J);
	 $ MAKE ABOVE⊗GB≡GC; ⊃;>,

TRANSFORM=
	<FOR I←1 STEP 1 UNTIL 10 DO
	    FOR J←1 STEP 1 UNTIL 3 DO XFRM[I,J]←REALIN(1);
	 $ MAKE XFORM⊗SCENE≡$ NEW(XFRM);>,


#B=	<NUMB←INTIN(1);
	FOR I←1 STEP 1 UNTIL NUMB DO
	BEGIN "B LOOP" INTEGER I;>,
BODYi=	< GETPNAME GB←$ NEW(FOURBY4);
		$ MAKE BODY⊗SCENE≡GB;>,
BODYNAME=<NEW_PNAME(GB,PNAME);>,

#P=	<NUMP←INTIN(1);
	FOR I←1 STEP 1 UNTIL NUMP DO
	BEGIN "P LOOP" >,
POINTi=	<GETPNAME GP←$ NEW(SIZE4);
	$ MAKE POINT⊗GB≡GP;>,
POINTNAME=<NEW_PNAME(GP,PNAME);>,
X=	<$ ∂(GP)[1]←REALSCAN(STR,BREAK);>,
Y=	<$ ∂(GP)[2]←REALSCAN(STR,BREAK);>,
Z=	<$ ∂(GP)[3]←REALSCAN(STR,BREAK);>,
W=	<$ ∂(GP)[4]←REALSCAN(STR,BREAK); END "P LOOP";>,

#L=	<NUML←INTIN(1);
	FOR I←1 STEP 1 UNTIL NUML DO
	BEGIN "L LOOP" >,
LINEi=	<GETPNAME GL←$ NEW(0.0);
		$ MAKE LINE⊗GB≡GL;>,
LINENAME=<NEW_PNAME(GL,PNAME);>,
ENDPTi=	<TOKEN GP←CVSI(PNAME,J);$ MAKE ENDPT⊗GL≡GP;>,
ENDPTj=	<TOKEN GP←CVSI(PNAME,J);$ MAKE ENDPT⊗GL≡GP;
		END "L LOOP";>,

#F=	<NUMF←INTIN(1);
	FOR I←1 STEP 1 UNTIL NUMF DO
	BEGIN "F LOOP" >,
FACEi=	<GETPNAME GF←$ NEW(SIZE4);
	$ MAKE FACE⊗GB≡GF; >,
FACENAME=<NEW_PNAME(GF,PNAME);>,
LINE1...LINEn=
	<TOKEN
	WHILE PNAME="G" DO
	⊂ GL←CVSI(PNAME,J);
	 IF J THEN ⊂ TYPE "CVIS LOSSAGE" EOM;
		  CALL(0,"EXIT") ⊃;
	 $ MAKE BOUNDARY⊗GF≡GL;
	 TOKEN ⊃; END "F LOOP"; END "B LOOP";>;


SETBREAK(ROW,'15,'12,"INS");
SETBREAK(PARE,"G","","INR");
SETBREAK(ID,"G0123456789","","XNR");

OPEN(1,"DSK",0,2,0,120,BREAK,EOF);
DO ⊂	TYPE "SEGMENTER FILENAME (.SEG) = " EOM;
	FILENAME←INCHWL&".SEG[DAT,RPO]";
	LOOKUP(1,FILENAME,I);
	IF I
	THEN TYPE "FILE "&FILENAME&" NOT FOUND." EOM;
	⊃ UNTIL ¬I;

α FILE FORMAT;

REPEAT #B TIMES

	BODYi		BODYNAME

	REPEAT #P TIMES		POINTi POINTNAME X Y Z W

	REPEAT #L TIMES		LINEi LINENAME ENDPTi ENDPTj

	REPEAT #F TIMES		FACEi FACENAME LINE1...LINEn

OCCLUDERS PROPERTY

ABOVES PROPERTY

TRANSFORM

α END OF FILE;
RELEASE(1);

∀ GB|$ BODY⊗SCENE≡GB DO
⊂ GSIV←$ NEW;
  $ MAKE BASE⊗GB≡GSIV;
  ∀ GF|$ FACE⊗GB≡GF DO
  ⊂ VSET←PHI;
    ∀ GL|$ BOUNDARY⊗GF≡GL DO VSET←VSET∪($ ENDPT⊗GL);
    ∀ GP|GPεVSET DO $ MAKE CORNER⊗GF≡GP ⊃ ⊃;

END "DISKSEG";
α	DISKOUT
output an ASCII file of data suitable for input to
a disc reading procedure in the PREDICTOR...paranoia
strikes deep...;

INTERNAL PROCEDURE DISKOUT;
BEGIN "DISKOUT"
INTEGER BREAK,EOF,FLAG,BODYNUM,I,J,K;
STRING ANS,FILENAME;
ITEMVAR GP;
SAFE REAL ARRAY ITEMVAR XF,GI;
DEFINE	OUTFILE=<1>, PRINT=<OUT(OUTFILE,>, !=<&↓);>,
	___=<);>, SEPARATE=<OUT(OUTFILE,↓&↓&↓&↓);>,
	CRLF=<OUT(OUTFILE,↓);>;

DEFINE	HEADING=<PRINT "RESULTS OF RECOGNIZER" !>,
	#BODY=<BODYNUM←LENGTH($ INSTANCE⊗ANY);
		SEPARATE
		PRINT "THERE ARE "&CVS(BODYNUM)&" INSTANCES." !
		SEPARATE	>,
	TIMES=<∀ GP,GI|$ INSTANCE⊗GP≡GI DO BEGIN "BLOOP">,
	PROTOTYPEi=<PRINT TAB&PRINTNAME(GP)&TAB ___>,
	BODYi=<PRINT TAB&PRINTNAME(GI) !>,
	TRANSFORMi=<FOR J←1 STEP 1 UNTIL 4 DO
		   ⊂	FOR K←1 STEP 1 UNTIL 4 DO
			PRINT CVG($ ∂(GI)[J,K]) ___
			PRINT "" ! ⊃;
		    SEPARATE
			END "BLOOP"; >,
	CAMERA=<ASSIGN XF|$ XFORM⊗SCENE≡XF HOLDS;
		PRINT "CAMERA TRANSFORM" !
		CRLF
		FOR J←1 STEP 1 UNTIL 10 DO
		⊂  FOR K←1 STEP 1 UNTIL 3 DO
		   PRINT CVG($ ∂(XF)[J,K]) ___
		   CRLF ⊃;	>,
	TRANSFORM=<	SEPARATE
			PRINT "EOF." !	>;


TYPE "WOULD YOU LIKE AN OUTPUT FILE FOR THE PREDICTOR ??" EOS;
IF ANS←INCHWL="Y" ∨ ANS="y"
THEN BEGIN "OUT IT"
	OPEN(OUTFILE,"DSK",0,0,2,120,BREAK,EOF);
  DO ⊂ "ENTER"
	TYPE "FILE NAME (.REC) = " EOS;
	FILENAME←INCHWL&".REC[DAT,RPO]";
	ENTER(OUTFILE,FILENAME,FLAG);
	IF FLAG
	THEN TYPE "ENTER FAILED!" EOM;
	⊃ "ENTER" UNTIL ¬FLAG;
	
α FILE FORMAT;

	HEADING
	SEPARATE

#BODY TIMES
	PROTOTYPEi  BODYi
	TRANSFORMi

CAMERA TRANSFORM

α EOF.;

	RELEASE(OUTFILE);
	END "OUT IT";
END "DISKOUT";
α	DISKPRE
input the results of the PREDICTOR;

INTERNAL PROCEDURE DISKPRE;
BEGIN "DISKPRE"
STRING FILENAME,PNAME,STR;
INTEGER	BREAK,EOF,FLAG,I,J,K,NUMLINES;
ITEMVAR GL;
SAFE REAL ARRAY ITEMVAR GP;
SAFE REAL ARRAY SIZE7[1:7];
DEFINE	ROW=<1>, PARE=<2>, ID=<3>,INFILE=<1>,
	NEXTLINE=<STR←INPUT(INFILE,ROW);>,
	TOKEN=<PNAME←SCAN(STR,PARE,BREAK);
		PNAME←SCAN(STR,ID,BREAK);>,
	GETPNAME=<DO ⊂ NEXTLINE TOKEN ⊃ UNTIL PNAME="G";>;

SETBREAK(ROW,'15,'12,"INS");
SETBREAK(PARE,"G","","INR");
SETBREAK(ID,"G0123456789","","XNR");

OPEN(1,"DSK",0,2,0,120,BREAK,EOF);
DO ⊂	TYPE "PREDICTOR FILENAME (.PRE assumed) = " EOM;
	FILENAME←INCHWL&".PRE[DAT,RPO]";
	LOOKUP(1,FILENAME,FLAG);
	IF FLAG
	THEN TYPE "FILE "&FILENAME&" NOT FOUND." EOM;
	⊃ UNTIL ¬FLAG;

DEFINE	#LINES=<NUMLINES←INTIN(INFILE);
		FOR I←1 STEP 1 UNTIL NUMLINES DO
		BEGIN "L IN">,
	LINEi=<GETPNAME
		GL←$ NEW(0.0);
		$ MAKE VISIBLE⊗SCENE≡GL;>,
	LINEPNAME=<NEW_PNAME(GL,PNAME);>,
	ENDPTi=<GETPNAME
		GP←CVSI(PNAME,FLAG);
		IF FLAG
		THEN GP←$ NEW(SIZE7);>,
	Xpp=<$ ∂(GP)[1]←REALIN(INFILE);>,
	Ypp=<$ ∂(GP)[2]←REALIN(INFILE);>,
	REPEAT=<>,TIMES=<>,
	EOF.=<END "L IN";>;

α FILE FORMAT;

REPEAT #LINES TIMES

	LINEi LINEPNAME
		ENDPTi	Xpp Ypp
		ENDPTi	Xpp Ypp

EOF.

END "DISKPRE";

α	COMPLETE
retures true if body is a complete projection
(i.e. an unoccluded object could look this way);

INTERNAL BOOLEAN PROCEDURE COMPLETE(ITEMVAR BODY);
BEGIN "COMPLETE"
	ITEMVAR P,F;
	SET ITEMVAR BS;
	BOOLEAN TBOOL;

α if some point of the body is a TJOINT, then remember the fact;
	TBOOL←FALSE;
	∀ P|POINT⊗BODY≡P DO
	IF FLAVOR⊗P≡TJOINT
	THEN TBOOL←TRUE;

α looks for FLAVOR of an endpt of an interior line of the body to
be a BADL;
	ASSIGN BS|EXTERIOR⊗BODY≡BS HOLDS;
	∀ P|POINT⊗BODY≡P DO
	IF LENGTH(ENDPT`P)=1 ∨
	    (FLAVOR⊗P≡BADL ∧ ((∂(BS) ∩ BOUNDARY`P)=PHI) ∧ (LENGTH(ENDPT`P)=2) ∧ ¬
	     TBOOL)
	THEN RETURN (FALSE);

	∀ F|FACE⊗BODY≡F DO
	IF LENGTH(BOUNDARY⊗F)<3
	THEN RETURN (FALSE);

	RETURN(TRUE);

       END "COMPLETE";

α	PARTPP
each model has associated with it a set of "projection pairs"
which consist of the number of vertices and number of faces
visible in each possible topologically distinct projection.
This procedure matches the count(pair) for the object in
question, B, against that for each of the prototypes and
reports all the possibilities;

INTERNAL PROCEDURE PARTPP(ITEMVAR B);
BEGIN "PARTPP"
	INTEGER N,NFACES,NVERTICES,FLAG;
	SAFE INTEGER ARRAY ITEMVAR P,U;

	TYPE "PARTPP - ENTERED" EOM;
	N←0;
	PMODS←PHI;
	NFACES←LENGTH(FACE⊗B);
	NVERTICES←LENGTH(POINT⊗B);
	TYPE TAB&PRINTNAME(B)&" "& CVS(NFACES)&", "&CVS(NVERTICES) EOM;
	TYPE TAB&"POINTS:" EOS;
	∀ P|POINT⊗B≡P DO TYPE PRINTNAME(P) EOS;
	TYPE "" EOM;
	TYPE TAB&"ACCEPTABLE PROTOTYPES:" EOS;
	∀ P|PεPROTOTYPES DO
	 ∀ U|PPAIR⊗P≡U DO
		IF ∂(U)[1]=NFACES ∧ ∂(U)[2]=NVERTICES
		THEN BEGIN
			PUT P IN PMODS;
			TYPE PRINTNAME(P) EOS;
			N←N+1;
			DONE;
			END;
	TYPE "" EOM;

	IF N=0
	THEN BEGIN
		PMODS←PROTOTYPES;
		TYPE TAB&"COMPLETE PROJECTION BUT NO PAIR MATCH FOUND." EOM;
		END;

	RETURN;

       END "PARTPP";
α	PARTFT
This procedure partitions the set of potential models based on
any "unusual" (i.e. non-quatrilateral) faces that are present.;

INTERNAL PROCEDURE PARTFT(ITEMVAR B);
BEGIN "PARTFT"
	ITEMVAR F,C;
	INTEGER K;
	SET S;

∀ F|FACE⊗B≡F DO
BEGIN
	LABEL LAB1;
	S←BOUNDARY⊗F;
 	∀ C|CORNER⊗F≡C DO
 	IF LENGTH(ENDPT`C ∩ S)≠2
	THEN BEGIN
		TYPE "PARTFT - REGION NOT COMPLETE." EOM;
		GO TO LAB1;
		END;

	K←LENGTH(BOUNDARY⊗F);
	IF K=3
	THEN BEGIN
		TYPE "PARTFT - THROW OUT RPP'S." EOM;
		PMODS←PMODS-{RPP114,RHOMBOID,CUBE,RPP112,RPP122,RPP124,
			LBEAM};
		S←PHI;
		RETURN;
		END;

	IF K=6
	THEN BEGIN
		TYPE "PARTFT - ONLY LBEAM REASONABLE." EOM;
		PMODS←{LBEAM};
		DONE;
		END;

LAB1:
	END;

TYPE "PARTFT - IT COULDN'T BE A WEDGE." EOM;
PMODS←PMODS-{WEDGE122,WEDGE124};
S←PHI;
RETURN;
END "PARTFT";

α	SUBSEG1
returns true if the edge set ES1 could possibly correspond to
a subset of the edges in set ES2.;

INTERNAL BOOLEAN PROCEDURE SUBSET1(SET ES1,ES2);
BEGIN "SUBSET1"
SET S,S1,OE;
REAL ITEMVAR L,E,BIG1,BIG2;


α compare the length of each line of the blob with the lines
of the model lines.  If the difference of the line lengths
is within the tolerance, then remove the model line from
the model line set (ES2):
	ES1 = set of blob lines of non-zero length
	ES2 = set of model lines
;

OE←PHI;
∀ L|LεES1 DO
BEGIN "SUB1"
	LABEL L1;
	IF ∂(L)>0
	THEN ∀ E|EεES2 DO
		IF ABS(GLB ∂(E)-∂(L))<
			(IF GLB ∂(E)<SUBSE1
			 THEN SUBSE2
			 ELSE GLB ∂(E)/SUBSE3)
		THEN BEGIN
			REMOVE E FROM ES2;
			DONE;
			END
		ELSE RETURN(FALSE)
	ELSE IF ∂(L)<0
	     THEN PUT L IN OE;
	END "SUB1";

WHILE LENGTH(OE)≠0 DO
BEGIN
α find the longest line in the set OE,and remove it from the set;
	BIG1←COP(OE);
	∀ L|LεOE DO
	IF ABS(∂(L))>ABS(∂(BIG1)) THEN BIG1←L;
	REMOVE BIG1 FROM OE;

α if a model line is longer than the big 1 then save it in a set S1;
	S1←PHI;
	∀ E|EεES2 DO
	IF GLB ∂(E)>ABS(∂(BIG1))-SUBSE4	THEN PUT E IN S1;

α if none were found, then failure;
	IF LENGTH(S1)=0
	THEN BEGIN
		S←S1←OE←PHI;
		RETURN (FALSE);
		END;

α remove the largest line from the set S1;
	BIG2←COP(S1);
	∀ L|LεS1 DO
	IF GLB ∂(L)>GLB ∂(BIG2) THEN BIG2←L;
	REMOVE BIG2 FROM ES2;
	END;

S←S1←OE←PHI;
RETURN(TRUE);
END "SUBSET1";


α	PARTBEL
This routine tries to further partition the set of possible
models based on the length of the base edges appearing
in the projection.

-NOTE:TEMPORARILY WE ARE ASSUMING HERE THAT ALL THE BODIES LIE IN THE;

INTERNAL PROCEDURE PARTBEL(ITEMVAR B);
BEGIN "PARTBEL"
SET ITEMVAR X;
REAL ITEMVAR F,Y,M;
INTEGER FLAG;
BOOLEAN BBOOL;
SET S1;

ASSIGN X| BASE⊗B≡X HOLDS;
∀ M|MεPMODS DO
BEGIN
	BBOOL←FALSE;
	S1←GLB EDGE⊗M;
	IF SUBSET1(∂(X),S1)
	THEN BBOOL←TRUE;
	IF ¬BBOOL
	THEN BEGIN
		REMOVE M FROM PMODS;
		TYPE "PARTBEL - IT COULDN'T BE A "&PRINTNAME(M)&"." EOM;
		END;
	END;

RETURN;
END "PARTBEL";

α	PARTBA
If base angle is not approximately 90 degrees, then the object
could not possibly be one that is totally rectalinear.;

INTERNAL PROCEDURE PARTBA(ITEMVAR B);
BEGIN "PARTBA"
	SET ITEMVAR X;
	REAL ITEMVAR L1,L2;
	SAFE REAL ARRAY ITEMVAR V1,V2,V3;
	INTEGER I;
	SET S;
	REAL ANG;

ASSIGN X|BASE⊗B≡X HOLDS;
∀ L1,L2|L1ε∂(X) ∧ L2ε∂(X) ∧ (L1≠L2) ∧ ADJ(L1,L2) DO
BEGIN
	ASSIGN V2|ENDPT⊗L1≡V2 ∧ ENDPT⊗L2≡V2 HOLDS;
	S←ENDPT⊗L1;
	REMOVE V2 FROM S;
	V1←COP(S);
	S←ENDPT⊗L2;
	REMOVE V2 FROM S;
	V3←COP(S);
	ANG←ANGLE(V1,V2,V3,3);
	IF ABS(ANG-90.0)≥PARBA1 THEN
	BEGIN
		TYPE "PARTBA - THROW OUT ALL RPP'S." EOM;
		PMODS←PMODS-{RPP114,CUBE,RPP112,RPP122,RPP124,LBEAM};
		S←PHI;
		RETURN;
		END;
	END;
S←PHI;
RETURN;
END "PARTBA";

α	PARTNVP
if there are no verticals visible in the projection,
assume it is not any of the totally rectilinear objects.
[This is not correct if the body is tilted in the scene!
Should look for parallelisms and/or conditions on the
base lines.];

INTERNAL PROCEDURE PARTNVP(ITEMVAR B);
BEGIN "PARTNVP"
	BOOLEAN BVERT;
	ITEMVAR L;

BVERT←FALSE;
∀ L|LINE⊗B≡L DO
IF VERT(L)
THEN BVERT←TRUE;

IF ¬BVERT
THEN BEGIN
	TYPE "PARTNVP - THROW OUT ALL RPP'S." EOM;
	PMODS←PMODS-{RPP114,CUBE,RPP112,RPP122,RPP124,LBEAM};
	RETURN;
	END;

RETURN;
END "PARTNVP";

α	PARTLAC
partition by actual lengths of edges meeting at the corners.
First, find lengths of all lines assumed vertical that
emanate from the base points.;

INTERNAL PROCEDURE PARTLAC(ITEMVAR B);
BEGIN "PARTLAC"
REAL ITEMVAR L,P,P1,M;
INTEGER FLAG;
BOOLEAN BOOL1;
SET S;

∀ M|MεPMODS DO
 ∀ P|POINT⊗B≡P DO
 BEGIN "LAC"
	LABEL LAB1;
	S←PHI;
α construct a set of non-zero length blob lines;
	∀ L|ENDPT⊗L≡P ∧ LINE⊗B≡L DO
	IF ∂(L)≠0
	THEN PUT L IN S;
	IF S=PHI THEN GO TO LAB1;
	BOOL1←FALSE;
	IF SUBSET1(S,GLB EDGE⊗M)
	THEN BOOL1←TRUE;
	IF ¬BOOL1
	THEN BEGIN "LAC2"
		REMOVE M FROM PMODS;
		TYPE "PARTLAC - IT COULDN'T BE A "&PRINTNAME(M) EOM;
		DONE;
		END "LAC2";
LAB1:
	END "LAC";

S←PHI;
RETURN;
END "PARTLAC";

END "RECOG0" ;